<template>
  <div id="app">
    <div class="content">
      <div v-for="(row,x) in list" :key="x" class="row">
        <item v-for="(item,y) in row" :x="x" :y="y" :key="y" :item="item" :current="current"/>
      </div>
    </div>
    <div class="right">
      <h4>下一个</h4>
      <div class="next">
        <div :class="['next-item',isNext(index)]" v-for="(item,index) in abc" :key="index"></div>
      </div>
      <h4>得分:{{grade}}</h4>
      <h4>等级:{{level}}</h4>
      <button @click="startGame">开始游戏</button>
    </div>
  </div>
</template>

<script>
import item from "./components/Item";
import _ from "lodash";
export default {
  name: "App",
  components: {
    item
  },
  data() {
    return {
      abc: new Array(16),
      list: null,
      current: [[-1, 0], [-1, 0]],
      next: null,
      timer: null,
      currentType: null,
      grade: 0,
      isFast: false,
      level: 1
    };
  },
  mounted() {
    this.initialize();
  },
  methods: {
    // 渲染下一个
    isNext(i) {
      let arr;
      if (!this.next) return "";
      switch (this.next.type) {
        case 1:
          arr = [5, 6, 9, 10];
          break;
        case 2:
          arr = [5, 1, 9, 13];
          break;
        case 3:
          arr = [9, 10, 6, 7];
          break;
        case 4:
          arr = [5, 6, 11, 10];
          break;
        case 5:
          arr = [5, 1, 9, 10];
          break;
        case 6:
          arr = [2, 6, 9, 10];
          break;
        case 7:
          arr = [11, 6, 9, 10];
          break;
      }
      if (arr.some(item => item === i)) return "abc";
    },
    // 移动函数
    move() {
      // 下一步的数组
      const arr1 = _.cloneDeep(this.current);
      arr1.forEach(item => {
        item[0] = item[0] + 1;
      });
      const result = this.stop(arr1);
      if (!result) {
        // 没到底的情况
        this.current = arr1;
      } else {
        // 到底的情况
        try {
          this.current.forEach(item => {
            this.list[item[0]].splice(item[1], 1, 1);
          });
          this.current = _.cloneDeep(this.next.content);
          this.currentType = this.next.type;
          this.random();
          this.clear();
          if (this.isFast) {
            clearInterval(this.timer);
            if (this.grade >= 50) {
              this.timer = setInterval(this.move, 300);
              this.isFast = false;
            } else {
              this.timer = setInterval(this.move, 500);
              this.isFast = false;
            }
          }
        } catch (error) {
          alert("game over");
          this.initialize();
        }
      }
    },
    // 停下来的条件
    stop(arr) {
      return (
        arr.some(item => item[0] >= 20) ||
        arr.some(
          item => this.list[item[0]] && this.list[item[0]][item[1]] === 1
        )
      );
    },
    // 监听键盘事件
    key() {
      document.addEventListener("keyup", this.keyUp);
    },
    // 消除方块函数
    clear() {
      const a = [];
      this.list.forEach((row, x) => {
        const result = row.every(item => {
          return item === 1;
        });
        if (result) {
          a.push(x);
        }
      });
      if (a.length > 0) {
        this.grade += a.length * 10;
        const arr1 = _.cloneDeep(this.list);
        a.forEach(item => {
          arr1.splice(item, 1);
          arr1.unshift([0, 0, 0, 0, 0, 0, 0, 0, 0, 0]);
        });
        this.list = arr1;
      }
    },
    // 随机生成方块
    random() {
      let a = Math.floor(Math.random() * 7 + 1);
      switch (a) {
        case 1:
          // o
          this.next = {
            type: 1,
            content: [[-2, 4], [-2, 5], [-1, 4], [-1, 5]]
          };
          break;
        case 2:
          // i
          this.next = {
            type: 2,
            content: [[-3, 4], [-2, 4], [-1, 4], [0, 4]]
          };
          break;
        case 3:
          // s
          this.next = {
            type: 3,
            content: [[-1, 5], [-1, 4], [0, 4], [0, 3]]
          };
          break;
        case 4:
          // z
          this.next = {
            type: 4,
            content: [[-1, 4], [-1, 5], [0, 5], [0, 6]]
          };
          break;
        case 5:
          // L
          this.next = {
            type: 5,
            content: [[-3, 4], [-2, 4], [-1, 4], [-1, 5]]
          };
          break;
        case 6:
          // j
          this.next = {
            type: 6,
            content: [[-3, 4], [-2, 4], [-1, 4], [-1, 3]]
          };
          break;
        case 7:
          // t
          this.next = {
            type: 7,
            content: [[-1, 4], [-1, 5], [-1, 6], [-2, 5]]
          };
          break;
      }
    },
    // 判断是否出界
    isGo(arr) {
      const result1 = arr.some(item => item[1] < 0);
      const result2 = arr.some(item => {
        return this.list[item[0]] && this.list[item[0]][item[1]] === 1;
      });
      const result3 = arr.some(item => item[1] > 9);
      const result4 = arr.some(item => item[0] > 19);
      if (!result1 && !result2 && !result3 && !result4) {
        this.current = arr;
      }
    },
    //开始游戏
    startGame() {
      this.initialize();
      this.key();
      this.timer = setInterval(this.move, 500);
      this.random();
      this.current = _.cloneDeep(this.next.content);
      this.currentType = this.next.type;
      this.random();
    },
    // 初始化
    initialize() {
      clearInterval(this.timer);
      const arr2 = Array.from(new Array(10), v => 0);
      const arr1 = Array.from(new Array(20), v => [...arr2]);
      this.list = arr1;
      this.current = [[-1, 0], [-1, 0]];
      this.next = null;
      this.currentType = null;
      this.grade = 0;
      this.level = 1;
      document.removeEventListener("keyup", this.keyUp);
    },
    // 监听键盘事件
    keyUp(e) {
      console.log(e.keyCode);
      if (e.keyCode === 37) {
        // 左
        const arr1 = _.cloneDeep(this.current);
        arr1.forEach(item => item[1]--);
        const result1 = arr1.some(item => item[1] < 0);
        let result2 = arr1.some(item => {
          if (this.list[item[0]]) {
            return this.list[item[0]][item[1]] === 1;
          }
        });
        if (!result1 && !result2) this.current = arr1;
      } else if (e.keyCode === 39) {
        // 右
        const arr1 = _.cloneDeep(this.current);
        arr1.forEach(item => item[1]++);
        const result1 = arr1.some(item => item[1] > 9);
        let result2 = arr1.some(item => {
          if (this.list[item[0]]) {
            return this.list[item[0]][item[1]] === 1;
          }
        });

        if (!result1 && !result2) this.current = arr1;
      } else if (e.keyCode === 38) {
        let arr = _.cloneDeep(this.current);
        // 上
        if (this.currentType === 1) {
          // o
          return;
        } else if (this.currentType === 2) {
          if (arr[0][1] === arr[3][1]) {
            // i
            arr[0][0]++;
            arr[0][1]--;
            arr[2][0]--;
            arr[2][1]++;
            arr[3][0] -= 2;
            arr[3][1] += 2;
          } else {
            arr[0][0]--;
            arr[0][1]++;
            arr[2][0]++;
            arr[2][1]--;
            arr[3][0] += 2;
            arr[3][1] -= 2;
          }
        } else if (this.currentType === 3) {
          // s
          if (arr[0][0] === arr[1][0] && arr[0][1] > arr[1][1]) {
            arr[0][1] -= 2;
            arr[1][0]++;
            arr[1][1]--;
            arr[3][0]++;
            arr[3][1]++;
          } else {
            arr[0][1] += 2;
            arr[1][0]--;
            arr[1][1]++;
            arr[3][0]--;
            arr[3][1]--;
          }
        } else if (this.currentType === 4) {
          // z
          if (arr[0][0] === arr[1][0] && arr[0][1] < arr[1][1]) {
            arr[0][0] += 2;
            arr[1][0]++;
            arr[1][1]--;
            arr[3][0]--;
            arr[3][1]--;
          } else {
            arr[0][0] -= 2;
            arr[1][0]--;
            arr[1][1]++;
            arr[3][0]++;
            arr[3][1]++;
          }
        } else if (this.currentType === 5) {
          // L
          if (arr[0][0] < arr[2][0] && arr[0][1] === arr[1][1]) {
            arr[0][0]++;
            arr[0][1]--;
            arr[2][0]--;
            arr[2][1]++;
            arr[3][0] -= 2;
          } else if (arr[0][0] == arr[2][0] && arr[0][1] < arr[2][1]) {
            arr[0][0]++;
            arr[0][1]++;
            arr[2][0]--;
            arr[2][1]--;
            arr[3][1] -= 2;
          } else if (arr[0][0] > arr[2][0] && arr[0][1] == arr[2][1]) {
            arr[0][0]--;
            arr[0][1]++;
            arr[2][0]++;
            arr[2][1]--;
            arr[3][0] += 2;
          } else {
            arr[0][0]--;
            arr[0][1]--;
            arr[2][0]++;
            arr[2][1]++;
            arr[3][1] += 2;
          }
        } else if (this.currentType === 6) {
          // L
          if (arr[0][0] < arr[2][0] && arr[0][1] === arr[1][1]) {
            arr[0][0]++;
            arr[0][1]--;
            arr[2][0]--;
            arr[2][1]++;
            arr[3][1] += 2;
          } else if (arr[0][0] == arr[2][0] && arr[0][1] < arr[2][1]) {
            arr[0][0]++;
            arr[0][1]++;
            arr[2][0]--;
            arr[2][1]--;
            arr[3][0] -= 2;
          } else if (arr[0][0] > arr[2][0] && arr[0][1] == arr[2][1]) {
            arr[0][0]--;
            arr[0][1]++;
            arr[2][0]++;
            arr[2][1]--;
            arr[3][1] -= 2;
          } else {
            arr[0][0]--;
            arr[0][1]--;
            arr[2][0]++;
            arr[2][1]++;
            arr[3][0] += 2;
          }
        } else if (this.currentType === 7) {
          // L
          if (arr[0][0] === arr[2][0] && arr[0][1] < arr[2][1]) {
            arr[0][0]++;
            arr[0][1]++;
            arr[2][0]--;
            arr[2][1]--;
            arr[3][0] += 1;
            arr[3][1] -= 1;
          } else if (arr[0][0] > arr[2][0] && arr[0][1] === arr[2][1]) {
            arr[0][0]--;
            arr[0][1]++;
            arr[2][0]++;
            arr[2][1]--;
            arr[3][0] += 1;
            arr[3][1] += 1;
          } else if (arr[0][0] === arr[2][0] && arr[0][1] > arr[2][1]) {
            arr[0][0]--;
            arr[0][1]--;
            arr[2][0]++;
            arr[2][1]++;
            arr[3][0] -= 1;
            arr[3][1] += 1;
          } else {
            arr[0][0]++;
            arr[0][1]--;
            arr[2][0]--;
            arr[2][1]++;
            arr[3][0] -= 1;
            arr[3][1] -= 1;
          }
        }
        this.isGo(arr);
      } else if (e.keyCode === 40) {
        this.isFast = true;
        clearInterval(this.timer);
        this.timer = setInterval(this.move, 50);
      }
    }
  },
  watch: {
    grade() {
      if (this.grade >= 50) {
        this.level = 2;
        clearInterval(this.timer);
        this.timer = setInterval(this.move, 300);
      }
    }
  }
};
;</script>

<style>
.row {
  display: flex;
  background: #ebebeb;
  width: 300px;
  height: 30px;
}
.content {
}
* {
  box-sizing: border-box;
}
#app {
  display: flex;
  justify-content: center;
}
.next-item {
  height: 30px;
  width: 30px;
}
.right {
  margin-left: 30px;
}
.next {
  display: flex;
  flex-wrap: wrap;
  width: 120px;
  background: #ebebeb;
}
.abc {
  background: rgb(92, 92, 92);
  border: 1px solid rgb(185, 185, 185);
}
</style>
